package com.wxsoft.java.proxy.cglib4.InterfaceMaker.demo;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.InterfaceMaker;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ConcreteClassNoInterface {

	public String getConcreteMethodA(String str) {
		System.out.println("ConcreteMethod A ... " + str);
		return str;
	}

	public int getConcreteMethodB(int n) {
		System.out.println("ConcreteMethod B ... " + n);
		return n + 10;
	}

	public int getConcreteMethodFixedValue(int n) {
		System.out.println("getConcreteMethodFixedValue..." + n);
		return n + 10;
	}

	public static void main(String[] s) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

		//interfaceOjb就是InterfaceMaker生成的接口，从接口名字可以看出。
		InterfaceMaker im = new InterfaceMaker();
		im.add(ConcreteClassNoInterface.class);
		Class interfaceOjb = im.create();
		System.out.println(interfaceOjb.isInterface());// true
		System.out.println(interfaceOjb.getName());// net.sf.cglib.empty.Object$$InterfaceMakerByCGLIB$$13e205f

		//看一下该接口内部的方法
		Method[] methods = interfaceOjb.getMethods();
		for (Method method : methods) {
			System.out.println(method.getName());
		}

		//下面通过生成的接口，可以对某个类进行Enhancer(本系列前面介绍过Enhancer，此处不再讲解)。
		Object obj = Enhancer.create(
//				Object.class,
				new NewConcreteClassNoInterface().getClass(),	//可修改成新的 代理 目标类
				new Class[] { interfaceOjb }, 
				new MethodInterceptor() {
					public Object intercept(Object obj, Method method,
							Object[] args, MethodProxy proxy) throws Throwable {
						System.out.println("新的 目标类 在 代理类中 执行 ");
						Object invokeSuper = proxy.invokeSuper(obj, args);
//						Object invokeSuper = method.invoke(obj, args);

						System.out.println("新的 目标类 在 代理类中 执行结束 ");
						return invokeSuper;
//						return "intercept!";
					}
				});

		Method method = obj.getClass().getMethod("getConcreteMethodA",
				new Class[] { String.class });
		System.out.println(method.invoke(obj, new Object[] { "12345" }));
		
		NewConcreteClassNoInterface im2 = (NewConcreteClassNoInterface) obj ;
		im2.getConcreteMethodA("asdf");
//		ConcreteClassNoInterface im3 = (ConcreteClassNoInterface) obj ;
//		im3.getConcreteMethodA("qwer");

	}
}


class NewConcreteClassNoInterface {

	public String getConcreteMethodA(String str) {
		System.out.println("this is new ConcreteMethod A ... " + str);
		return str;
	}
}
